package indi.zjh.dp.util;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.TimeUnit;

import indi.zjh.dp.error.CommandExecuteException;
import jdk.nashorn.internal.ir.ThrowNode;

public class SystemCmd {

    /**
     * 执行系统命令, 返回执行结果
     *
     * @param cmd 需要执行的命令
     * @param dir 执行命令的子进程的工作目录, null 表示和当前主进程工作目录相同
     */
    public static String exec(String cmd, File dir) throws Exception {
        StringBuilder result = new StringBuilder();

        Process process = null;
        BufferedReader bufrIn = null;
        BufferedReader bufrError = null;

        try {
            // 执行命令, 返回一个子进程对象（命令在子进程中执行）
            process = Runtime.getRuntime().exec(cmd, null, dir);

            // 方法阻塞, 等待命令执行完成（成功会返回0）
            process.waitFor();

            // 获取命令执行结果, 有两个结果: 正常的输出 和 错误的输出（PS: 子进程的输出就是主进程的输入）
            bufrIn = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
            bufrError = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));

            // 读取输出
            String line = null;
            while ((line = bufrIn.readLine()) != null) {
                result.append(line).append('\n');
            }
            while ((line = bufrError.readLine()) != null) {
                result.append(line).append('\n');
            }
            int ret = process.exitValue();
            if(ret != 0)
            {
            	throw new CommandExecuteException(result.toString(), ret);
            }
        } finally {
            closeStream(bufrIn);
            closeStream(bufrError);

            // 销毁子进程
            if (process != null) {
                process.destroy();
            }
        }

        // 返回执行结果
        return result.toString();
    }

    private static void closeStream(Closeable stream) {
        if (stream != null) {
            try {
                stream.close();
            } catch (Exception e) {
                // nothing
            }
        }
    }
    
    
    
    
    
    
    
    public static String execCMD(String cmd, int timeout) throws CommandExecuteException {  
        Process process = null;  
        StringBuilder sbStd = new StringBuilder();  
        StringBuilder sbErr = new StringBuilder();

        long start = System.currentTimeMillis() / 1000;  
        try {  
            //if (envs == null) {  
        	
                //process = Runtime.getRuntime().exec(cmd, null, null);  
                process = Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", cmd }, null, null);  
            //} else {  
            //    process = Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", cmd }, envs);  
            //}  
      
            BufferedReader brStd = new BufferedReader(new InputStreamReader(process.getInputStream()));  
            BufferedReader brErr = new BufferedReader(new InputStreamReader(process.getErrorStream()));  
            String line = null;  
      
            while (true) {  
                if (brStd.ready()) {  
                    line = brStd.readLine();  
                    sbStd.append(line + "\n");  
                    continue;  
                }   
                if (brErr.ready()) {  
                    line = brErr.readLine();  
                    sbErr.append(line + "\n");  
                    continue;  
                }   
                  
                if (process != null) {  
                    try {     
                        process.exitValue();     
                        break;  
                    } catch (IllegalThreadStateException e) {     
                    }     
                }  
                  
                if (System.currentTimeMillis() / 1000 - start > timeout) {
                	sbErr.append(cmd+", ");
                    sbErr.append("命令执行超时退出.");  
                    break;  
                }  
                  
                try {  
                    TimeUnit.MILLISECONDS.sleep(500);  
                } catch (InterruptedException e) {  
                }  
            }  
        } catch (IOException e) {  
        } finally {  
            if (process != null) {
                process.destroy();
            }  
        }
        
//        System.out.println("execCMD |"+cmd+"|");
//        System.out.println("std:|"+sbStd.toString()+"|");
//        System.out.println("err:|"+sbErr.toString()+"|");
          
        if (sbErr.toString().length()>0) {
        	System.out.println("prepare to throw CommandExecuteException");
            throw new CommandExecuteException(sbErr.toString(), 1);
        } else {  
            return sbStd.toString().trim();  
        }  
    }  
    

}